package com.wx.sign;

import com.wx.Base64Utils;
import com.wx.Constant.CommonConstant;
import org.apache.commons.lang3.StringUtils;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

/**
 * AES 加密解密
 * <p>
 * 注意确认 IV_STR(向量)
 * PADDING (加密方式已经补位方式)
 */
public class AESUtils {

    private static final String IV_STR = "qazwert12345!@#$";
    private static final String PADDING = "AES/CBC/PKCS5Padding";//算法/模式/补码方式

    /**
     * 加密
     *
     * @param data
     * @param key
     * @return
     * @throws Exception
     */
    public static String encrypt(String data, String key) throws Exception {
        if (StringUtils.isBlank(data)) {
            throw new Exception("encrypt data can't null or empty");
        }
        if (StringUtils.isEmpty(key)) {
            throw new Exception("encrypt key can't null or empty");
        }

        Key skeySpec = getKeyBy(key);
        Cipher cipher = Cipher.getInstance(PADDING);
        IvParameterSpec iv = new IvParameterSpec(IV_STR.getBytes());
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);//使用CBC模式，需要一个向量iv，可增加加密算法的强度
        byte[] encrypted = cipher.doFinal(data.getBytes(CommonConstant.CHAR_SET));

        return Base64Utils.encode(encrypted);
    }

    /**
     * 解密
     *
     * @param data
     * @param key
     * @return
     * @throws Exception
     */
    public static String decrypt(String data, String key) throws Exception {


        if (StringUtils.isBlank(data)) {
            throw new Exception("decrypt data can't null or empty");
        }
        if (StringUtils.isEmpty(key)) {
            throw new Exception("decrypt key can't null or empty");
        }

        Key skeySpec = getKeyBy(key);
        Cipher cipher = Cipher.getInstance(PADDING);
        IvParameterSpec iv = new IvParameterSpec(IV_STR.getBytes());
        cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);

        byte[] encrypted = Base64Utils.decode(data);
        byte[] original = cipher.doFinal(encrypted);
        return new String(original, CommonConstant.CHAR_SET);
    }

    private static SecretKeySpec getKey(String strKey) throws Exception {
        byte[] arrBTmp = strKey.getBytes();
        byte[] arrB = new byte[16]; // 创建一个空的16位字节数组（默认值为0）
        for (int i = 0; i < arrBTmp.length && i < arrB.length; i++) {
            arrB[i] = arrBTmp[i];
        }
        return new SecretKeySpec(arrB, "AES");
    }

    private static Key getKeyBy(String strKey) {
        try {
            KeyGenerator keyGen = KeyGenerator.getInstance("AES");
            SecureRandom random = new SecureRandom();
            random.setSeed(strKey.getBytes());
            keyGen.init(128, random);

            Key key = keyGen.generateKey();
            return key;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void main(String[] args) {
        String str = "haha you are good man";
        String key = "1234567890123456";
        try {
            String encrytStr = encrypt(str, key);
            System.out.println(encrytStr);
            String originStr = decrypt(encrytStr, key);
            System.out.println(originStr);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void test() {
        System.out.println("zheshiwo de test 哈哈这里是要测试的我现在还没有理解rsa的       akldsjfaklsjf;" +
                "lkjwoeiropjkkjkjkjkfakjfksdjf;kladjfkasd");
    }
}
